package org.engine.core;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;

import java.util.ArrayList;
import java.util.List;

public class RuleFactory {
    private static final Logger logger = LoggerFactory.getLogger(RuleFactory.class);

    /**
     * Json String 转换为 Rule 对象
     *
     * @param ruleConfig
     * @return
     */
    public static AbstractRule parseRule(String ruleConfig) throws Exception {
        JSONObject jsonConfig = JSON.parseObject(ruleConfig);
        if (!jsonConfig.containsKey(RuleConstant.PARSE_ID)) {
            logger.error("规则没有包含id节点");
            throw new Exception("规则没有包含id节点");
        }
        AbstractRule abstractRule = parseRule(jsonConfig);
        abstractRule.setId(jsonConfig.getString(RuleConstant.PARSE_ID));
        return abstractRule;
    }

    private static AbstractRule parseRule(JSONObject config) throws Exception {
        if (!config.containsKey(RuleConstant.PARSE_CLASS)) {
            logger.error("规则没有包含class节点");
            throw new Exception("规则没有包含class节点");
        }
        // 获取rule class
        AbstractRule rule = ContextLoader.getCurrentWebApplicationContext().getBean(config.getString(RuleConstant.PARSE_CLASS), AbstractRule.class);

        /**放入相关属性*/
        if (config.containsKey(RuleConstant.PARSE_NAME)) {
            rule.setName(config.getString(RuleConstant.PARSE_NAME));
        } else {
            rule.setName(rule.getClass().getSimpleName());
        }

        if (config.containsKey(RuleConstant.PARSE_RULE_CONFIG)) {
            rule.setRuleConfig(config.getJSONObject(RuleConstant.PARSE_RULE_CONFIG));
        }

        if (config.containsKey(RuleConstant.PARSE_SILENCE)) {
            rule.setIgnoreResult(config.getBoolean(RuleConstant.PARSE_SILENCE));
        }

        if (config.containsKey(RuleConstant.PARSE_EXECUTE_ALL)) {
            rule.setExecuteAllChildren(config.getBoolean(RuleConstant.PARSE_EXECUTE_ALL));
        }

        if (config.containsKey(RuleConstant.PARSE_CHILDREN)) {
            JSONArray jsonArray = config.getJSONArray(RuleConstant.PARSE_CHILDREN);
            if (jsonArray.size() > 0) {
                List<AbstractRule> childrenRuleList = new ArrayList<>();
                for (int i = 0; i < jsonArray.size(); i++) {
                    childrenRuleList.add(parseRule(jsonArray.getJSONObject(i)));
                }
                rule.setChildrenRule(childrenRuleList);
            }
        }
        return rule;
    }
}
